\documentclass[twoside,colorback,accentcolor=tud4c,11pt]{tudreport}
\usepackage{ngerman}

\usepackage[utf8]{inputenc}

\usepackage{listings}
\lstset{
numbers=left,
numberstyle=\footnotesize,
frame=l,
breaklines=true,
basicstyle=\footnotesize,
showstringspaces=false
}

\usepackage[stable]{footmisc}
\usepackage[ngerman,pdfview=FitH,pdfstartview=FitV]{hyperref}

\usepackage{booktabs}
\usepackage{multirow}
\usepackage{longtable}

\newlength{\longtablewidth}
\setlength{\longtablewidth}{0.675\linewidth}

\title{Praktikum adaptive Computersysteme}
\subtitle{Ausarbeitung\\2. Phase: Messungen}
\subsubtitle{Wilko Kunert, Alexander Schleich}
\lowertitleback{\hfill\today}
\institution{Embedded Systems \& Applications}

\begin{document}
\maketitle

\tableofcontents

\chapter{Messmethodik}\label{chap:Messmethodik}

Ziel der zweiten Phase des Praktikums adaptive Computersysteme ist die Messung der Anzahl von Takten, 
die zwischen zwei Zugriffen von der CPU auf die RCU liegen. Dafür müssen die Takte 
zwischen zwei aufeinanderfolgenden steigendenden Flanken des \textit{ADDRESSED}-Signals 
(bei deaktiviertem \textit{RESET}-Signal) gezählt werden. Anschließend sollen die Minima 
und Maxima der ermittelten Werte für verschiedene Zugriffsmuster (nur Lese-Operationen, nur Schreib-Operationen, 
abwechselnd Lese- und Schreiboperationen) ausgegeben werden. In Abbildung~\ref{fig:messmethodik} 
ist die Methodik beispielhaft widergegeben:

\begin{figure}[h]
\centering
\includegraphics[width=\linewidth]{graphics/messmethodik.png}
\caption{Drei Zugriffe mit unterschiedlichen Taktabständen zueinander}
\label{fig:messmethodik}
\end{figure}

Zu Beginn sind die Register \textit{cycleCounter}, \textit{cycleMin} und \textit{cycleMax} mit Standardwerten 
belegt die anzeigen, dass bisher kein Zugriff statt gefunden hat (4294967295 entspricht 0xFFFFFFFF). 
Durch die erste steigende Taktflanke auf dem \textit{ADDRESSED}-Signal beginnt das Register \textit{cycleCounter} 
mit der Zählung. Durch die zweite steigende Taktflanke wird das Register zurückgesetzt und die Zählung wird neugestartet. 
Das Ergebnis der letzten Zählung wird mit den Inhalten der Register \textit{cycleMin} und \textit{cycleMax} 
abgeglichen und überschreibt diese wenn der Inhalt größer bzw. kleiner ist.

Um die Messergebnisse nicht zu verfälschen werden die Zugriffe auf die Register der Zähler nicht berücksichtigt. 
Außerdem mussten wir zusätzlich eine Möglichkeit einbauen die Zähler (ohne Auslösen eines 
globalen \textit{RESET}-Signals) zurückzusetzen, um mehrere Messungen hintereinander durchführen zu können. 
Dies bewerkstelligen wir durch einen Zugriff auf eine für diesen Zweck reservierte Adresse.

\chapter{HDL-Modell}\label{chap:HdlModell}
 
Das in Phase 1 erstellte Slave-Modul (reverse) haben wir im Folgenden um einen Zaehler-Block erweitert.
Weiterhin legen wir je nach Kodierung von ADDRESS[3:2] entweder das Ergebnis der minimalen oder der maximalen 
Anzahl von gemessenen Taktzyklen auf den DATAOUT Ausgang. Standardmaessig (Das heisst momentan genau dann 
wenn ADDRESS[3:2] == 00) liegt result auf dem Ausgang. (Zeile 34).\\
Da wir fuer die Messung wissen muessen, wann eine neue aufsteigene Taktflanke von ADDRESSED auftritt,
muessen wir den "`alten"' Wert von ADDRESSES jeweils speichern. Dies tun wir im reg addressedLastCycle.
Weiterhin haben wir regs fuer die aktuelle Anzahl an Taktzyklen (durch den Counter gesetzt) sowie
die bisher minimalen und maximalen gemessenen Taktzyklen. \\
Unser Zaehler beginnt in Zeile 65 und reagiert wenn ADDRESSED auf 1 ist und addressedLastCycle auf 0.
Weiterhin erwarten wir, dass ein Lesevorgang auf das Result-Register vorliegt (ADDRESS[3:2] == 00). \\
Folgend pruefen wir nun ob bereits ein vorheriger Zugriff vorgelegen hat(Zeile 83), das heisst cycleCounter
besitzt einen validen Wert (ungleich 0xFFFFFFFF). Ist das der Fall pruefen wir ob cycleCounter kleiner
als das bisherige Minimum, sowie groesser als das bisherige Maximum war und aendern beide Werte falls noetig. \\
In jedem Fall wird unser Zaehler neugestartet (Zeile 96) und mit 0x1 initialisiert. \\
Falls in diesem Takt keine Aenderung von ADDRESSED stattgefunden (Zeile 99) hat wird cycleCounter lediglich
um 1 erhoeht, sowie addressedLastCycle auf den aktuellen ADDRESSED Wert gesetzt. \\
Durch diesen recht einfachen Block sind wir in der Lage unabhaengig von WRITE und Burst Zugriffen
die gewuenschten Taktzyklen zu messen.
  
%\begin{figure}[h] 
%\centering
%\begin{minipage}{\linewidth}
%\lstset{language=Verilog,linewidth=0.9\linewidth}
%\begin{lstlisting} 
%module user(
%	    CLK, // Systemtakt
%	    RESET, // systemweiter Reset
%	    ADDRESSED, // High, wenn RC von CPU angesprochen wird
%	    WRITE, // High, wenn CPU auf RC schreiben will
%	    DATAIN, // von der CPU auf die RC geschriebene Daten
%	    DATAOUT, // von der CPU aus der RC gelesene Daten
%	    ADDRESS, // Addresse des Zugriffs
%	    IRQ // Loest Interrupt an an CPU aus
%	    );
%\end{lstlisting}
%\end{minipage}
%\caption{user.v - Moduldeklaration}
%\end{figure}

\begin{figure}[h]
\centering
\begin{minipage}{\linewidth}
\lstset{language=Verilog,linewidth=0.9\linewidth,firstnumber=11}
\begin{lstlisting}
   // Eingaenge
   input           CLK;
   input           RESET;
   input           ADDRESSED;
   input           WRITE;
   input [31:0]    DATAIN;
   input [23:2]    ADDRESS;

   // Ausgaenge
   output [31:0]   DATAOUT;
   output          IRQ;
   wire 	   IRQ = 1'b0; // wird im Slave-Mode nicht gebraucht  

   // Beginn der Anwendung **************************************************
   reg [31:0] 	   result; // Ergebnisregister
   reg [31:0] 	   reversed; // Zwischenergebnis
   reg 		   addressedLastCycle; // ADDRESSED Signal des letzten Takts
   reg [31:0] 	   cycleCounter; // Takte seit der letzten steigenden Flanke
   reg [31:0] 	   cycleLast; // Takte zw. den letzten beiden steigenden Flanken
   reg [31:0] 	   cycleMin; // min. Takte zw. zwei steigenden ADDRESSED Flanken
   reg [31:0] 	   cycleMax; // max. Takte zw. zwei steigenden ADDRESSED Flanken
   
   // Ausgabedaten auf Bus legen
   assign DATAOUT = (ADDRESS[3:2] == 2'b01) ? cycleLast : 
		    (ADDRESS[3:2] == 2'b10) ? cycleMin : 
		    (ADDRESS[3:2] == 2'b11) ? cycleMax : 
		    result;

   // Berechne als Zwischenergebnis immer die
   // bitverdrehte Reihenfolge des Dateneingang
   always @(DATAIN)
     begin : reverseDataIn
	integer n;
	for (n=0; n<32; n=n+1)
	  begin
	     reversed[n] = DATAIN[31-n];
	  end	
     end

   // Steuerung
   always @(posedge CLK or posedge RESET)
     begin
	// initialisiere Ergebnis auf magic number fuer Debugging
	if (RESET)
	  begin
	     result <= 32'hDEADBEEF;
	  end
	// Schreibzugriff auf RC, neu berechnetes Zwischenergebnis uebernehmen
	else if (ADDRESSED && WRITE)
	  begin
	     result <= reversed;
	  end
     end
\end{lstlisting}
\end{minipage}
\caption{user.v - Port- und Registerdeklaration, Ausgabe und Steuerung}
\end{figure}

\begin{figure}[h]
\centering
\begin{minipage}{\linewidth}
\lstset{language=Verilog,linewidth=0.9\linewidth,firstnumber=64}
\begin{lstlisting}
   // Zaehler
   always @(posedge CLK or posedge RESET)
     begin
	// initialisiere Zaehler (bei globalem und lokakem Reset-Signal)
	if (RESET || (ADDRESSED && (ADDRESS[4:4] == 2'b1)))
	  begin
	  	 cycleLast <= 32'hffffffff;
	     cycleMin <= 32'hffffffff;	
	     cycleMax <= 32'h00000000;
	     cycleCounter <= 32'hffffffff;
	     addressedLastCycle <= 0;
	  end
	// neue steigende ADDRESSED Taktflanke
	else
	  begin
	     // erkenne steigende Taktflanke (bei Zugriff auf Result-Register)
	     if (!addressedLastCycle && ADDRESSED && (ADDRESS[3:2] == 2'b00))
	       begin
		  // setze Minimum/Maximum ab dem zweiten Zugriff
		  if (cycleCounter < 32'hffffffff)
		    begin
		       if (cycleCounter < cycleMin)
			 begin
			    cycleMin <= cycleCounter;
			 end
		       if (cycleCounter >= cycleMax)
			 begin
			    cycleMax <= cycleCounter;
			 end	
		       cycleLast <= cycleCounter;
		    end
		  // Zaehler (neu-)starten
		  cycleCounter <= 32'h00000001;
	       end
	     // erhoehe Zaehler ab dem ersten Zugriff
	     else if (cycleCounter < 32'hffffffff)
	       begin
		  cycleCounter <= cycleCounter + 1;
	       end
	     // speichere letzten ADDRESSED Zustand
	     addressedLastCycle <= ADDRESSED;
	  end
     end
   
endmodule
\end{lstlisting}
\end{minipage}
\caption{user.v - Zähler}
\end{figure}


\chapter{C-Programm}\label{chap:CProgram}

Unsere Software besteht grundsaetzlich aus vier Abschnitten.

\begin{enumerate}
  \item (Zeile 1 - 20) enthaelt den C-Rumpf sowie grundlegende Initialisierungen fuer die Verbindung zur Hardware.
  \item (Zeile 22 - 35) enthaelt den reinen ``Lesen''-Anteil.
  \item (Zeile 36 - 49) enthaelt den reinen ``Schreiben''-Anteil.
  \item (Zeile 50 - 62) enthaelt den Mix aus Schreiben und Lesen.
\end{enumerate}

Zeile 20 - 66 wird jeweils 25 mal durchgefuerht um eine ausreichend grosse Anzahl an Messergebnissen zu erhalten. \\
Wir haben uns hier bewusst dafuer entschieden die Einzelzugriffe nicht in Schleifen zu verpacken, um die Messergebnisse
nicht durch evtl. Branch-Prediction Methodiken zu verfaelschen. \\
Ein letzter Test mit Schleifen hat ergeben, dass in sich die Taktzahlen in jedem Fall recht drastisch verringern.
Moeglicherweise werden mit Schleifen Burst-Zugriffe durchgefuehrt was wir durch unsere Einzelzugriffe verhindert haben.

\begin{figure}[h]
\centering
\begin{minipage}{\linewidth}
\lstset{language=C,linewidth=0.9\linewidth,firstnumber=1}
\begin{lstlisting}
#include <stdio.h>
#include <stdlib.h>
#include <acev/rcu.h>
#include <signal.h>

main()
{

  // benutze vorzeichenlose Ganzzahlen (32b Worte) fuer alle Daten
  unsigned long m, word;

  // Zeiger auf RC-Adressraum
  volatile unsigned long *rcu;

  // RC initialisieren
  rcu_init();

  // Zeiger auf RC-Adressraum holen
  rcu = rcu_get_s0(NULL);
\end{lstlisting}
\end{minipage}
\caption{main.c - Initialisierung}
\end{figure}

\begin{figure}[h]
\centering
\begin{minipage}{\linewidth}
\lstset{language=C,linewidth=0.9\linewidth,firstnumber=20}
\begin{lstlisting}
  for (m=0; m<25; m++) {
        
    // nur Lesen
    word = rcu[0];
    word = rcu[0];
    ...
    word = rcu[0];
    word = rcu[0];

    printf("Nur Lesen:\n");
    printf("Min: 0x%08x / %d Takte\n", rcu[2], rcu[2]);
    printf("Max: 0x%08x / %d Takte\n", rcu[3], rcu[3]);
  
    // setze Zaehler zurueck
    word = rcu[5];

    // nur Schreiben
    rcu[0] = word;
    rcu[0] = word;
    ...
    rcu[0] = word;
    rcu[0] = word;

    printf("Nur Schreiben:\n");
    printf("Min: 0x%08x / %d Takte\n", rcu[2], rcu[2]);
    printf("Max: 0x%08x / %d Takte\n", rcu[3], rcu[3]);

    // setze Zaehler zurueck
    word = rcu[5];

    // Schreiben und Lesen
    rcu[0] = word;
    word = rcu[0];
    ...
    rcu[0] = word;
    word = rcu[0];

    printf("Schreiben und Lesen:\n");
    printf("Min: 0x%08x / %d Takte\n", rcu[2], rcu[2]);
    printf("Max: 0x%08x / %d Takte\n", rcu[3], rcu[3]);
    
    // setze Zaehler zurueck
    word = rcu[5];    
    
  }  

}
\end{lstlisting}
\end{minipage}
\caption{main.c - Messung}
\end{figure}

\chapter{Messergebnisse}\label{chap:Messergebnisse}

Auf folgender Tabelle sind unsere Messergebnisse festgehalten. Es faellt sofort auf, dass Lesen im Durchschnitt 
am Laengsten dauert (minimal 9 und maximal 31,16 Takte). Schreiben geht ein weniger schneller (minimal 7 und maximal 28 Takte). \\
Interessanterweise geht der Mix aus Schreiben und Lesen am schnellsten (minimal 4 und maximal 26,84 Takte). \\
Auch in den gemittelten Taktzahlen (ueber Maximum und Minimum) ist dieser Trend vorhanden (Schreiben: 20,08, Lesen: 17,5 Lesen + Schreiben: 15,42).

\begin{figure}[h]
\centering
\includegraphics[width=.8\textwidth]{graphics/MessergebnisseTabelle_cropped.pdf}
\caption{Messergebnisse bei 25 Zugriffen}
\label{fig:messegebnisseTabelle}
\end{figure}

\begin{figure}[h]
\centering
\includegraphics[width=.5\textwidth]{graphics/DurchschnittMin_cropped.pdf}
\caption{Durchschnittliche minimale Anzahl an Taktzyklen}
\label{fig:durchschnittMin}
\end{figure}

\begin{figure}[h]
\centering
\includegraphics[width=.5\textwidth]{graphics/DurchschnittMax_cropped.pdf}
\caption{Durchschnittliche maximale Anzahl an Taktzyklen}
\label{fig:durchschnittMax}
\end{figure}


\begin{figure}[h]
\centering
\includegraphics[width=.5\textwidth]{graphics/DurchschnittTakte_cropped.pdf}
\caption{Durchschnittliche Anzahl an Taktzyklen}
\label{fig:durchschnittTakte}
\end{figure}

\end{document}
